home *** CD-ROM | disk | FTP | other *** search
- #define NAME "XpkMasterPrefs"
- #define REVISION "16"
- //#define DEBUG
-
- /* Programmheader
-
- Name: XpkMasterPrefs
- Author: SDI
- Distribution: PD
- Description: xpk prefs loader, like IPrefs
- Compileropts: -
- Linkeropts: -gsi (no startup)
-
- 1.0 25.12.96 : first Version
- 1.1 26.12.96 : nearly redefined xpkprefs structures - a lot of changes
- 1.2 27.12.96 : some fixes
- 1.3 30.12.96 : did a bit on Recog function
- 1.4 02.01.97 : added correctness check of BufPattern
- 1.5 11.01.97 : corrected some errors
- 1.6 28.02.97 : changed some semaphore specific stuff
- 1.7 01.03.97 : added Version info to MainPrefs
- 1.8 07.03.97 : fixed RecogFunc
- 1.9 24.03.97 : added DEBUG stuff
- 1.10 28.03.97 : added last function and ReadArgs
- 1.11 02.04.97 : XpkTypeData changed, ListData now internal structure
- 1.12 03.04.97 : added DEBUG info, debuged RecogFunction
- 1.13 04.04.97 : buffer now 2 K
- 1.14 06.06.97 : name pattern no case independant
- 1.15 17.06.97 : fixed error, when no name and no filepattern
- 1.16 18.06.97 : added filelength check and OR parameter
- */
-
- /*
- How to parse the type list:
- - The struct XpkTypeData of the first matching structure is returned.
- - If no type matches, the default is returned.
- - Scan goes always in linear order from the beginning to end. (and never
- reverse).
- - if no file name is given, the xtp_FilePattern field is ignored.
- */
-
- #include <pragma/exec_lib.h>
- #include <pragma/dos_lib.h>
- #include <pragma/iffparse_lib.h>
- #include <prefs/prefhdr.h>
- #include <xpk/xpkprefs.h>
- #include <exec/memory.h>
- #include "SDI_defines.h"
- #define SDI_TO_ANSI
- #include "SDI_ASM_STD_protos.h"
-
-
- /**************************************************************************
- *
- * Standard prefs specific data structure. xps_PrefsData points to this.
- *
- * xssd_TypeList nodes are of type XpkTypeNode.
- *
- *
- */
-
- struct XpkStdSemaphoreData {
- struct List xssd_TypeList; /* list of file types */
- ULONG xssd_Buffer1Size; /* size of following buffer */
- STRPTR xssd_Buffer1; /* pointer to buffer */
- };
-
- struct XpkTypeNode {
- struct Node xtn_Node; /* standard node structure */
- ULONG xtn_Size; /* hold complete size to free */
- struct XpkTypePrefs xtn_TypePrefs; /* real data */
- };
-
- #define RECOGBUFSIZE 2048
-
- #define PARAM "QUIT/S"
-
- #ifdef __MAXON__
- #define __asm
- struct Library *IFFParseBase;
- #else
- #define iffparsebase IFFParseBase
- #endif
-
- struct DosLibrary *DOSBase;
-
- void CorrectAdr(APTR pos, APTR mempos);
- void DoPrefsCreation(struct XpkPrefsSemaphore *sem);
- void ClearTypeList(struct XpkStdSemaphoreData *sem);
- void ClearMainPrefs(struct XpkPrefsSemaphore *sem);
- struct XpkTypeData * __asm RecogFunc(register __a0 STRPTR buf,
- register __a1 STRPTR name, register __a2 STRPTR printname,
- register __d0 ULONG bufsize, register __d1 ULONG fullsize);
-
- UBYTE CheckHex(STRPTR *data, LONG number);
- ULONG CheckBufPattern(STRPTR pattern);
- UBYTE GetCharacter(STRPTR pattern);
- /* these two return zero, when name matches or defined values, when not */
- ULONG CheckPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize);
- ULONG MatchBufPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize);
- ULONG MatchFileName(STRPTR pattern, STRPTR name);
-
- #define MATCHERR_PATTERN_INCORRECT 1
- #define MATCHERR_NO_MEMORY 2
- #define MATCHERR_BUFFER_TO_SHORT 3
- #define MATCHERR_NO_MATCH 4
- #define MATCHERR_NO_SIZE_MATCH 5
-
- ULONG start(void) /* not named main, to get error with startup code ! */
- {
- struct DosLibrary *dosbase;
- struct XpkPrefsSemaphore *semaphore;
- struct Process *task;
- struct Message *msg = 0;
- struct RDArgs *rda;
- LONG quit = 0;
-
- if(!(task = (struct Process *) FindTask(0))->pr_CLI)
- {
- WaitPort(&task->pr_MsgPort);
- msg = GetMsg(&task->pr_MsgPort);
- /* no tooltype check now, so means always start semaphore */
- }
- else
- {
- if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
- {
- DOSBase = dosbase;
- if((rda = ReadArgs(PARAM, &quit, 0)))
- FreeArgs(rda);
- CloseLibrary((struct Library *) dosbase);
- }
- /* does not recognize failed ReadArgs - normal start in this case */
- }
-
- if(quit)
- {
- Forbid();
- if((semaphore = (struct XpkPrefsSemaphore *) FindSemaphore(XPKPREFSSEMNAME)))
- {
- ObtainSemaphoreShared((struct SignalSemaphore *) semaphore);
- Signal(semaphore->xps_MasterTask, SIGBREAKF_CTRL_C);
- ReleaseSemaphore((struct SignalSemaphore *) semaphore);
- }
- Permit();
- }
- else if(!FindSemaphore(XPKPREFSSEMNAME) &&
- (dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
- {
- DOSBase = dosbase;
- if((semaphore = (struct XpkPrefsSemaphore *) AllocMem(sizeof(struct
- XpkPrefsSemaphore) + sizeof(struct XpkStdSemaphoreData), MEMF_PUBLIC|MEMF_CLEAR)))
- {
- struct NotifyRequest *notifyrequest;
-
- struct XpkStdSemaphoreData *sd = (struct XpkStdSemaphoreData *)
- (((STRPTR) semaphore) + sizeof(struct XpkPrefsSemaphore));
- // both structures are allocated with one AllocMem
-
- semaphore->xps_Semaphore.ss_Link.ln_Type = NT_SEMAPHORE;
- semaphore->xps_Semaphore.ss_Link.ln_Name = XPKPREFSSEMNAME;
- semaphore->xps_PrefsData = sd;
- // semaphore->xps_Version = 0;
- semaphore->xps_PrefsType = XPREFSTYPE_STANDARD;
- // semaphore->xps_ProgressFunc = 0;
- semaphore->xps_RecogSize = RECOGBUFSIZE;
- semaphore->xps_RecogFunc = (struct XpkTypeData *(*)()) RecogFunc;
- semaphore->xps_MasterTask = (struct Task *) task;
-
- sd->xssd_TypeList.lh_Type = NT_USER;
- sd->xssd_TypeList.lh_Head = (struct Node *) &sd->xssd_TypeList.lh_Tail;
- sd->xssd_TypeList.lh_TailPred = (struct Node *) &sd->xssd_TypeList.lh_Head;
-
- InitSemaphore((struct SignalSemaphore *) semaphore);
- AddSemaphore((struct SignalSemaphore *) semaphore);
-
- if((notifyrequest = (struct NotifyRequest *)
- AllocMem(sizeof(struct NotifyRequest), MEMF_CLEAR)))
- {
- ULONG signr;
-
- if((signr = AllocSignal(-1L)) != -1)
- {
- notifyrequest->nr_Name = "ENV:xpkmaster.prefs";
- notifyrequest->nr_Flags = NRF_SEND_SIGNAL | NRF_NOTIFY_INITIAL;
- notifyrequest->nr_stuff.nr_Signal.nr_Task = FindTask(0);
- notifyrequest->nr_stuff.nr_Signal.nr_SignalNum = signr;
- if((StartNotify(notifyrequest)) == DOSTRUE)
- {
- ULONG signal = 0;
- while(!(signal & SIGBREAKF_CTRL_C))
- if((signal = Wait(1 << signr | SIGBREAKF_CTRL_C)) & (1 << signr))
- DoPrefsCreation(semaphore);
- EndNotify(notifyrequest);
- }
- FreeSignal(signr);
- }
- FreeMem(notifyrequest, sizeof(struct NotifyRequest));
- }
- ObtainSemaphore((struct SignalSemaphore *) semaphore);
- RemSemaphore((struct SignalSemaphore *) semaphore);
- ClearTypeList((struct XpkStdSemaphoreData *) semaphore->xps_PrefsData);
- ClearMainPrefs(semaphore);
-
- FreeMem(semaphore, sizeof(struct XpkPrefsSemaphore) +
- sizeof(struct XpkStdSemaphoreData));
- }
- CloseLibrary((struct Library *) dosbase);
- }
-
- if(msg)
- {
- Forbid();
- ReplyMsg(msg);
- }
-
- return 0;
- }
-
- /* changes relative addresses into normal ones */
- void CorrectAdr(APTR pos, APTR mempos)
- {
- if(*(ULONG *)pos)
- *(ULONG *)pos += (ULONG) mempos;
- }
-
- void ClearTypeList(struct XpkStdSemaphoreData *sd)
- {
- struct Node *n;
-
- while((n = RemHead(&sd->xssd_TypeList)))
- FreeMem(n, ((struct XpkTypeNode *) n)->xtn_Size);
- }
-
- void ClearMainPrefs(struct XpkPrefsSemaphore *sem)
- {
- struct XpkStdSemaphoreData *sd = (struct XpkStdSemaphoreData *) sem->xps_PrefsData;
- if(sd->xssd_Buffer1)
- FreeMem(sd->xssd_Buffer1, sd->xssd_Buffer1Size);
- sem->xps_MainPrefs = 0;
- sd->xssd_Buffer1Size = 0;
- sd->xssd_Buffer1 = 0;
- }
-
- void DoPrefsCreation(struct XpkPrefsSemaphore *sem)
- {
- struct Library *iffparsebase;
- struct ContextNode *cn;
- struct IFFHandle *iff;
- ULONG prefsversion = 0;
-
- ObtainSemaphore(&sem->xps_Semaphore);
-
- ClearTypeList((struct XpkStdSemaphoreData *) sem->xps_PrefsData);
- ClearMainPrefs(sem);
-
- if(!(iffparsebase = OpenLibrary("iffparse.library", 37)))
- return;
-
- #ifdef __MAXON__
- IFFParseBase = iffparsebase;
- #endif
-
- if((iff = AllocIFF()))
- {
- if((iff->iff_Stream = Open("ENV:xpkmaster.prefs", MODE_OLDFILE)))
- {
- InitIFFasDOS(iff);
- if(!OpenIFF(iff, IFFF_READ))
- {
- LONG a[] = { ID_PREF, ID_PRHD, ID_PREF, ID_XPKT, ID_PREF, ID_XPKM};
- if(!StopChunks(iff, a, 3))
- {
- ULONG error = 0;
-
- while(!error)
- {
- if(ParseIFF(iff,IFFPARSE_SCAN))
- break;
-
- cn = CurrentChunk(iff);
-
- switch(cn->cn_ID)
- {
- case ID_PRHD:
- {
- struct PrefHeader prh;
- ReadChunkBytes(iff, &prh, sizeof(struct PrefHeader));
- prefsversion = prh.ph_Version;
- /* use this, when internal version is greater than one. In this
- case the value is version of XPKT chunks */
- } break;
- case ID_XPKT:
- {
- struct XpkTypeNode *buf;
- ULONG size;
- size = cn->cn_Size + sizeof(struct Node) + sizeof(ULONG);
- if((buf = (struct XpkTypeNode *) AllocMem(size, MEMF_PUBLIC|MEMF_CLEAR)))
- {
- struct XpkTypePrefs *pref = &buf->xtn_TypePrefs;
-
- ReadChunkBytes(iff, pref, cn->cn_Size);
- CorrectAdr(&pref->xtp_NamePattern, pref);
- CorrectAdr(&pref->xtp_FilePattern, pref);
- CorrectAdr(&pref->xtp_TypeName, pref);
- CorrectAdr(&pref->xtp_PackerData, pref);
- buf->xtn_Node.ln_Name = pref->xtp_TypeName;
- buf->xtn_Node.ln_Type = NT_USER;
- buf->xtn_Size = size;
- pref->xtp_PackerData->xtd_Memory = 0;
- pref->xtp_PackerData->xtd_MemorySize = 0;
- AddTail(&((struct XpkStdSemaphoreData *)sem->xps_PrefsData)->xssd_TypeList, (struct Node *) buf);
- }
- else error = 1;
- } break;
- case ID_XPKM:
- {
- struct XpkMainPrefs *pref;
- struct XpkStdSemaphoreData *sd =
- (struct XpkStdSemaphoreData *) sem->xps_PrefsData;
- struct XpkTypeData *p;
-
- ClearMainPrefs(sem);
-
- if((pref = (struct XpkMainPrefs *) AllocMem(cn->cn_Size, MEMF_PUBLIC|MEMF_CLEAR)))
- {
- ReadChunkBytes(iff, pref, cn->cn_Size);
- CorrectAdr(&pref->xmp_DefaultType, pref);
- p = pref->xmp_DefaultType;
- /* XpkTypeData newer than version 0 may be incorrect, so set to 0 */
- p->xtd_Version = 0;
- p->xtd_Memory = 0;
- p->xtd_MemorySize = 0;
- sem->xps_MainPrefs = pref;
- sd->xssd_Buffer1Size = cn->cn_Size;
- sd->xssd_Buffer1 = (STRPTR) pref;
- }
- else error = 1;
- } break;
- }
- }
- }
- CloseIFF(iff);
- }
- Close(iff->iff_Stream);
- }
- FreeIFF(iff);
- }
- CloseLibrary(IFFParseBase);
- ReleaseSemaphore(&sem->xps_Semaphore);
- }
-
- UBYTE CheckHex(STRPTR *data, LONG number)
- {
- LONG num;
- do
- {
- num = number;
- while(num-- && isxdigit(*((*data)++)))
- ;
- if(++num)
- return MATCHERR_PATTERN_INCORRECT;
- } while(isxdigit(**data));
- return 0;
- }
-
- /* return 0, when pattern is valid */
- ULONG CheckBufPattern(STRPTR pattern)
- {
- while(*pattern)
- {
- ULONG a;
- STRPTR s;
-
- s = pattern;
-
- switch(*(pattern++))
- {
- case 'l': a = 1; break;
- case 'h': a = 1; break;
- case 'm': a = 1; break;
- case 'v': a = 2; break;
- case 'r': a = 4; break;
- case 'g': a = 4; break;
- case 's': a = 2; break;
- case '|': a = 0; break;
- default: return MATCHERR_PATTERN_INCORRECT; break;
- }
- if(a && CheckHex(&pattern, a))
- return MATCHERR_PATTERN_INCORRECT;
-
- if((*s == 'm' && (pattern-s) > 5) ||
- ((*s == 'l' || *s == 'h') && (pattern-s) > 9))
- return MATCHERR_PATTERN_INCORRECT;
- /* only word data for 'm' and longword for 'l' and 'h' + 1 '.' */
- }
-
- return 0;
- }
-
- UBYTE GetCharacter(STRPTR pattern)
- {
- UBYTE i = 0, c;
- ULONG size = 2;
- while(size--)
- {
- i <<= 4;
- if((c = toupper(*(pattern++))) >= 'A')
- i += c + 10 - 'A';
- else
- i += c - '0';
- }
- return i;
- }
-
- ULONG CheckPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize)
- {
- STRPTR bufpos = buffer;
- ULONG i;
- UBYTE j, k;
- STRPTR errpos, str;
-
- while(*pattern && *pattern != '|')
- {
- switch(*(pattern++))
- {
- case 'm':
- i = strtoul(pattern, &errpos, 16);
- pattern = errpos; /* first non hex char is next command */
- if(i >= size)
- return MATCHERR_BUFFER_TO_SHORT;
- else
- bufpos = buffer + i;
- break;
- case 'l':
- i = strtoul(pattern, &errpos, 16);
- pattern = errpos; /* first non hex char is next command */
- if(fsize > i)
- return MATCHERR_NO_SIZE_MATCH;
- break;
- case 'h':
- i = strtoul(pattern, &errpos, 16);
- pattern = errpos; /* first non hex char is next command */
- if(fsize < i)
- return MATCHERR_NO_SIZE_MATCH;
- break;
- case 'v':
- while(isxdigit(*pattern))
- {
- j = GetCharacter(pattern); pattern += 2;
- if(bufpos >= buffer + size)
- return MATCHERR_BUFFER_TO_SHORT;
- if(j != *(bufpos++))
- return MATCHERR_NO_MATCH;
- }
- break;
- case 'r':
- while(isxdigit(*pattern))
- {
- errpos = buffer;
- k = GetCharacter(pattern); pattern += 2;
- j = GetCharacter(pattern); pattern += 2;
- while(errpos < buffer + size)
- {
- if(*errpos >= k && *errpos <= j)
- return MATCHERR_NO_MATCH;
- ++errpos;
- }
- }
- break;
- case 'g':
- while(isxdigit(*pattern))
- {
- k = GetCharacter(pattern); pattern += 2;
- j = GetCharacter(pattern); pattern += 2;
- if(bufpos >= buffer + size)
- return MATCHERR_BUFFER_TO_SHORT;
- if(*bufpos < k && *bufpos > j)
- return MATCHERR_NO_MATCH;
- ++bufpos;
- }
- break;
- case 's':
- bufpos = buffer;
- while(isxdigit(*pattern))
- {
- str = pattern;
- j = GetCharacter(str); str += 2;
- while(bufpos < buffer + size && *bufpos != j)
- ++bufpos;
- if(*bufpos == j)
- {
- errpos = ++bufpos;
- while(isxdigit(*str) && bufpos < buffer + size &&
- GetCharacter(str) == *bufpos)
- {
- str += 2; ++bufpos;
- }
- if(!isxdigit(*str))
- pattern = str; /* exits while loop */
- else
- bufpos = errpos; /* reset buffer */
- }
- else
- return MATCHERR_NO_MATCH;
- }
- break;
- default: return MATCHERR_NO_MATCH; break;
- }
- }
- return 0;
- }
-
- ULONG MatchBufPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize)
- {
- ULONG err = MATCHERR_NO_MATCH;
-
- if(CheckBufPattern(pattern))
- {
- #ifdef DEBUG
- Printf("MatchBufPattern: CheckBufPattern(%s) failed\n", pattern);
- #endif
- return MATCHERR_PATTERN_INCORRECT;
- }
-
- while(*pattern)
- {
- if(!(err = CheckPattern(pattern, buffer, size, fsize)))
- return 0;
- else /* search for next OR field or end of pattern */
- {
-
- while(*pattern && *pattern != '|')
- ++pattern;
- if(*pattern == '|')
- ++pattern;
- }
- }
-
- return err;
- }
-
- ULONG MatchFileName(STRPTR pattern, STRPTR name)
- {
- ULONG a, b = MATCHERR_NO_MATCH;
- STRPTR buf;
-
- a = (strlen(pattern)<<1) + 10; // pattern match buffer
-
- if(!(buf = (STRPTR) AllocMem(a, MEMF_ANY)))
- return MATCHERR_NO_MEMORY;
-
- if(ParsePatternNoCase(pattern, buf, a) >= 0 && MatchPatternNoCase(buf, name))
- b = 0;
-
- FreeMem(buf, a);
-
- return b;
- }
-
- struct XpkTypeData * __asm RecogFunc(register __a0 STRPTR buf,
- register __a1 STRPTR name, register __a2 STRPTR printname,
- register __d0 ULONG bufsize, register __d1 ULONG fullsize)
- {
- struct XpkPrefsSemaphore *sem;
- struct XpkTypePrefs *xp;
- struct Node *n;
-
- if(!buf || !bufsize)
- return 0;
-
- sem = (struct XpkPrefsSemaphore *) FindSemaphore(XPKPREFSSEMNAME);
- /* I can do without ObtainSemaphore, because when I'm called here the
- semaphore is owned already and surely exists */
-
- if(sem->xps_PrefsData)
- {
- for(n = ((struct XpkStdSemaphoreData *)sem->xps_PrefsData)->
- xssd_TypeList.lh_Head; n->ln_Succ; n = n->ln_Succ)
- {
- xp = &((struct XpkTypeNode *) n)->xtn_TypePrefs;
-
- if((name && xp->xtp_Flags & XPKT_NamePattern) ||
- xp->xtp_Flags & XPKT_FilePattern)
- {
- if(!(xp->xtp_Flags & XPKT_FilePattern) || !MatchBufPattern(
- xp->xtp_FilePattern, buf, bufsize, fullsize))
- {
- if(!name || !(xp->xtp_Flags & XPKT_NamePattern) || !MatchFileName(
- xp->xtp_NamePattern, name))
- {
- #ifdef DEBUG
- Printf("RecogFunc: matched '%s'\n", xp->xtp_TypeName);
- #endif
- return xp->xtp_PackerData;
- }
- #ifdef DEBUG
- else
- Printf("RecogFunc: no namematch '%s'\n", xp->xtp_TypeName);
- #endif
- }
- #ifdef DEBUG
- else
- Printf("RecogFunc: no bufmatch '%s'\n", xp->xtp_TypeName);
- #endif
- }
- #ifdef DEBUG
- else
- Printf("RecogFunc: no patterns '%s'\n", xp->xtp_TypeName);
- #endif
- }
- }
-
- if(sem->xps_MainPrefs)
- return sem->xps_MainPrefs->xmp_DefaultType;
-
- return 0;
- }
-
-